package com.kly.user.serviceImpl.traffic.wlm;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;
import com.google.common.collect.Maps;
import com.google.common.eventbus.AsyncEventBus;
import com.kly.enums.ParameterTypeEnum;
import com.kly.service.MemberService;
import com.kly.user.db.dao.*;
import com.kly.user.db.entity.*;
import com.kly.user.dto.TrafficSourceDto;
import com.kly.user.dto.vo.TrafficSourceReq;
import com.kly.user.enums.AppEnum;
import com.kly.user.enums.LikeEnum;
import com.kly.user.enums.TrafficSourceEnum;
import com.kly.user.enums.UserType;
import com.kly.user.eventbus.ActionEnum;
import com.kly.user.eventbus.Event;
import com.kly.user.service.UserTrafficSourceService;
import com.kly.user.service.WhiteListService;
import com.kly.user.task.UserTaskConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public abstract class WLMBase {

    public static Log logger = LogFactory.getLog(WLMBase.class);

    @Autowired
    UserDao userDao;

    @Resource
    MemberService memberService;


    @Resource
    AsyncEventBus pushEventBus;
    @Resource
    IssueUserDao issueUserDao;

    @Autowired
    CustomersUserDao customersUserDao;


    @Resource
    AsyncEventBus asyncEventBus;


    @Resource
    UserTaskConfig userTaskConfig;

    @Resource
    UserWlmDao userWlmDao;
    @Resource
    UserWlmLogDao userWlmLogDao;

    @Resource
    IssueWlmRecordDao issueWlmRecordDao;

    @Resource
    CustomersDao customersDao;

    @Resource
    UserTrafficSourceService userTrafficSourceService;

    @Resource
    WhiteListService whiteListService;

    @NacosValue(value = "${pp.wlm.issue.fix.user}", autoRefreshed = true)
    public String ppWlmIssueFixUserCode;



    public void dealCondition(IssueConfigEntity issueConfigEntity, UserEntity userEntity) {

    }

    public int getWLMIssueTime(IssueConfigEntity issueConfigEntity, Integer wlmAmount) {
        return issueConfigEntity.getIssueOne() + (wlmAmount * issueConfigEntity.getIssueTwo());
    }


    public static boolean isToday(Date date) {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        //格式化为相同格式
        return fmt.format(date).equals(fmt.format(new Date()));
    }

    public Integer wlmAmount(String userCode) {
//        List<UserWlmEntity> todayWlmRecords = userWlmDao.getTodayWlmRecords(userCode);
//        return todayWlmRecords.size();
        return issueWlmRecordDao.getWlmNum(userCode);
    }


    public boolean isOrganic(UserEntity currentUser) {
        TrafficSourceReq req = TrafficSourceReq.builder()
                .userCode(currentUser.getUserCode())
                .appCode(currentUser.getAppCode())
                .mobile(currentUser.getMobile())
                .email(currentUser.getEmail())
                .build();
        Response<TrafficSourceDto> resp = userTrafficSourceService.getTrafficSource(req);
        if (!resp.isSuccess() || resp.getData() == null) {
            return false;
        }

        // 如果开关关闭，一律走非自然流量策略；如果开关开启，自然流量走自然流量策略
        return TrafficSourceEnum.Organic.equals(resp.getData().getTrafficSourceEnum());
    }

    public long distanceWLMTime(String userCode) {
        UserWlmEntity todayWlmRecord = userWlmDao.getLastWlmRecord(userCode);
        return DateUtil.between(DateUtil.date(), todayWlmRecord.getSendWlmTime(), DateUnit.MINUTE);
    }


    public void addUserWlm(String userCode, String userCodeFriend, String app) {
        UserWlmEntity userWlmEntity = new UserWlmEntity();
        userWlmEntity.setUserCode(userCodeFriend);
        userWlmEntity.setUserCodeWlm(userCode);
        userWlmEntity.setWlmType(LikeEnum.LIKE.getType());
        userWlmEntity.setSendWlmTime(new Date());
//        userWlmEntity.setConnectType(WLMType.WLM.getCode());
        userWlmDao.insert(userWlmEntity);

        userWlmLogDao.addWlmLog(userWlmEntity);

        addWLMRecord(userCode, userCodeFriend);
        // 推送消息
        pushMessage(userCodeFriend, userCode, AppEnum.getEnumByUserAppFlat(app));
    }

    public void pushMessage(String fromUseCode, String toUserCode, AppEnum appEnum) {

        pushEventBus.post(buildEvent(fromUseCode, toUserCode, appEnum));

//        String message = "Flash chat⚡\uFE0F     \n" +
//                "When you are hit by a flash chat, don't wait, click on the dialog box to contact ta immediately!";
//        asyncSendMsgService.sendMsg("1113913307465977856", userCode, "RC:InfoNtf", message, message);

    }

    public Event buildEvent(String fromUseCode, String toUserCode, AppEnum appEnum) {
        Map<String, Integer> params = Maps.newHashMap();
        params.put("type", ParameterTypeEnum.WHO_LIKE_ME.getId());
        return Event.builder().eventActionEnum(ActionEnum.PUSH_MSG).fromUserCode(fromUseCode).toUserCode(toUserCode).app(appEnum).content(JSONObject.toJSONString(params)).build();
    }

    public void addWLMRecord(String userCode, String userCodeFriend) {
        IssueWlmRecordEntity issueWlmRecordEntity = new IssueWlmRecordEntity();
        issueWlmRecordEntity.setUserCode(userCode);
        issueWlmRecordEntity.setModelUserCode(userCodeFriend);
        UserEntity userEntity = userDao.selectByUserCode(userCodeFriend);
        issueWlmRecordEntity.setOnlineStatus(userEntity.getOnline());
        issueWlmRecordDao.insert(issueWlmRecordEntity);
    }


    /**
     * 是否走非自然流量策略
     * <p>
     * 【pp-v1.1.0】流量侧-自然流量>>wlm>>2. 仅下发本次提供的user code（类似素人建联）优先下发在线的user code，其次下发不在线的user code，不区分性别
     */
    public Integer getFilterUsertype(String userCode) {
        UserEntity currentUser = userDao.selectByUserCode(userCode);
        CustomersEntity customer = customersDao.getByUserCode(currentUser.getUserCode());
        TrafficSourceReq req = TrafficSourceReq.builder()
                .userCode(currentUser.getUserCode())
                .appCode(currentUser.getAppCode())
                .mobile(currentUser.getMobile())
                .email(currentUser.getEmail())
                .adId(customer != null ? customer.getDeviceId() : null)
                .build();
        Response<TrafficSourceDto> resp = userTrafficSourceService.getTrafficSource(req);
        if (!resp.isSuccess() || resp.getData() == null) {
            return UserType.ALL.getType();
        }

        // 过滤CM 如果开关关闭，一律走非自然流量策略；如果开关开启，自然流量走自然流量策略
        if (TrafficSourceEnum.Organic.equals(resp.getData().getTrafficSourceEnum())) {
            return UserType.NORMAL_USER.getType();
        }

        return UserType.ALL.getType();
    }


    public boolean checkInWhiteList(String userCode) {
        UserEntity target = userDao.selectByUserCode(userCode);
        if (target == null) {
            // todo 异常处理
            return false;
        }

        Response<Boolean> result = whiteListService.in(target.getAppCode(), target.getUserCode(), target.getMobile(), target.getEmail());
        return result.getData();
    }


    public String getUser(String userCode, int lookingFor, Boolean currentUserInWhiteList) {
        List<String> userCodeList = new ArrayList<>();

        logger.info("WLMIssueTask userCode" + userCode);
        Response<Boolean> response = memberService.ifMember(userCode);
        if (response.isSuccess()) {
            Boolean ifmMember = response.getData();
            logger.info("WLMIssueTask ifmMember" + ifmMember);
            List<Integer> poolNums = new ArrayList<>();
            if (ifmMember) {
                poolNums.add(1);
            } else {
                poolNums.add(2);
                poolNums.add(3);
                poolNums.add(4);
            }
            logger.info("===WLMIssueTask, 流量池:" + poolNums);
            List<IssueUserPoolEntity> userCodeEntityList = new ArrayList<>();
            //【pp-v1.1.0】流量侧-自然流量>>wlm>>2. 仅下发本次提供的user code（类似素人建联）优先下发在线的user code，其次下发不在线的user code，不区分性别
            CustomersUserEntity customersUserEntity = customersUserDao.getCustomer(userCode);
            if (customersUserEntity == null) {
                logger.error("===WLMIssueTask, 当前用户 没有 对应的customer_code:" + poolNums);
                userCodeEntityList = userDao.queryIssueUserPoolV2(userCode, lookingFor, poolNums, 1, UserType.ALL.getType());
            } else {
                logger.info("===WLMIssueTask, 当前用户 找到 对应的customer_code:" + poolNums);
                userCodeEntityList = userDao.queryIssueUserPoolV3(userCode,customersUserEntity.getCustomerCode(), lookingFor, poolNums, 1, currentUserInWhiteList ? UserType.MODEL.getType() : UserType.ALL.getType());
            }
            if (CollectionUtils.isNotEmpty(userCodeEntityList)) {
                logger.info("===WLMIssueTask, userCode:{}, 返回数据: {}", userCode, JSONObject.toJSONString(userCodeEntityList));
                userCodeList = userCodeEntityList.stream().map(IssueUserPoolEntity::getUserCode).collect(Collectors.toList());
            } else {
                logger.info("===WLMIssueTask,找不到能下发wlm的mmodel:" + poolNums);
            }
        }

        String result = null;
        if (!userCodeList.isEmpty()) {
            result = userCodeList.get(0);
            issueUserDao.updateConnectCount(userCodeList);
        }

        return result;
    }

    public String getUser_bak(String userCode, int lookingFor,Boolean userInWhite) {
        List<String> userCodeList = new ArrayList<>();

        logger.info("wlmgetuser userCode" + userCode);
        Response<Boolean> response = memberService.ifMember(userCode);
        if (!response.isSuccess()) {
            return null;
        }

        Boolean ifmMember = response.getData();
        logger.info("wlmgetuser ifmMember" + ifmMember);
        List<Integer> poolNums = new ArrayList<>();
        if (ifmMember) {
            poolNums.add(1);
        } else {
            poolNums.add(2);
            poolNums.add(3);
            poolNums.add(4);
        }

        logger.info("===newWlmV2, 流量池:" + poolNums);
        List<IssueUserPoolEntity> userCodeEntityList = userDao.queryIssueUserPoolV2(userCode, lookingFor, poolNums, 1, userInWhite ? UserType.MODEL.getType() : UserType.ALL.getType());

        logger.info("===newWlmV2, userCode:{}, 返回数据: {}", userCode, JSONObject.toJSONString(userCodeEntityList));
        if (CollectionUtils.isNotEmpty(userCodeEntityList)) {
            userCodeList = userCodeEntityList.stream().map(IssueUserPoolEntity::getUserCode).collect(Collectors.toList());
        }


        String result = null;
        if (!userCodeList.isEmpty()) {
            result = userCodeList.get(0);
            issueUserDao.updateConnectCount(userCodeList);
        }
        return result;
    }

}
